/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package javax.servlet.http;

import java.io.IOException;

import javax.servlet.ServletResponseWrapper;

/**
 * HttpServletResponseWrapper提供了一个简便实现类，在对HttpServletResponse有改动需求的时，可以重写此类，之后Response的操作都会经过重写的类.
 * Provides a convenient implementation of the HttpServletResponse interface that
 * can be subclassed by developers wishing to adapt the response from a Servlet.
 * This class implements the Wrapper or Decorator pattern. Methods default to
 * calling through to the wrapped response object.
 * 
 * @author 	Various
 *
  * @since	v 2.3
 *
 * @see 	HttpServletResponse
 *
 */

public class HttpServletResponseWrapper extends ServletResponseWrapper implements HttpServletResponse {


    /** 
    * Constructs a response adaptor wrapping the given response.
    * @throws IllegalArgumentException if the response is null
    */
    public HttpServletResponseWrapper(HttpServletResponse response) {
	    super(response);
    }
    
    private HttpServletResponse _getHttpServletResponse() {
	return (HttpServletResponse) super.getResponse();
    }
    
    /**
     * 设置指定Cookie到response中.
     * 可以被多次调用，可以设置多个Cookie.
     * The default behavior of this method is to call addCookie(Cookie cookie)
     * on the wrapped response object.
     */
    public void addCookie(Cookie cookie) {
	this._getHttpServletResponse().addCookie(cookie);
    }

    /**
     * 判断response中是否包含某个响应头.
     * The default behavior of this method is to call containsHeader(String name)
     * on the wrapped response object.
     */

 
    public boolean containsHeader(String name) {
	return this._getHttpServletResponse().containsHeader(name);
    }
    
    /**
     * 对指定URL进行编码，编码后包含会话ID，若逻辑判断不需要编码，则返回原URL.
     * 此方法的实现需包括：确定会话ID是否需要包含在编码后的URL中，例如，当浏览器支持Cookie时，或者URL重写（会话跟踪）被关闭时，则不需要URL编码，直接返回原URL.
     * 对于健壮的会话跟踪，Servlet发出的所有URL都应该通过这个方法运行.否则，URL重写不能用于不支持Cookie的浏览器.
     *
     * The default behavior of this method is to call encodeURL(String url)
     * on the wrapped response object.
     */
    public String encodeURL(String url) {
	return this._getHttpServletResponse().encodeURL(url);
    }

    /**
     * 对指定URL进行编码，编码后包含会话ID，若逻辑判断不需要编码，则返回原URL.
     * HttpServletResponse.sendRedirect调用前，需调用此方法进行URL编码.
     * 此方法包括是否包含会话ID的逻辑.
     * 此方法包含会话ID的逻辑与encodeURL(String url)是不同的，所以进行了分离.
     * 所有发送到HttpServletResponse.sendRedirect方法应通过此方法运行，否则，URL重写不能用于不支持cookies的浏览器.
     *
     * The default behavior of this method is to return encodeRedirectURL(String url)
     * on the wrapped response object.
     */
    public String encodeRedirectURL(String url) {
	return this._getHttpServletResponse().encodeRedirectURL(url);
    }

    /**
     * 已弃用，使用encodeURL(String url).
     * The default behavior of this method is to call encodeUrl(String url)
     * on the wrapped response object.
     */
    public String encodeUrl(String url) {
	return this._getHttpServletResponse().encodeUrl(url);
    }
    
    /**
     * 已弃用，使用encodeRedirectURL(String url).
     * The default behavior of this method is to return encodeRedirectUrl(String url)
     * on the wrapped response object.
     */
    public String encodeRedirectUrl(String url) {
	return this._getHttpServletResponse().encodeRedirectUrl(url);
    }
    
    /**
     * 写入指定的状态码和错误描述信息，并清除缓冲区，将错误响应给客户端.
     * 如果响应已经提交，此方法将抛出一个IllegalStateException，使用此方法后，应将响应视为已提交，不应写入.
     * The default behavior of this method is to call sendError(int sc, String msg)
     * on the wrapped response object.
     */
    public void sendError(int sc, String msg) throws IOException {
	this._getHttpServletResponse().sendError(sc, msg);
    }

    /**
     * 写入指定的状态码，并清除缓冲区，将错误响应给客户端.
     * 如果响应已经提交，此方法将抛出一个IllegalStateException，使用此方法后，应将响应视为已提交，不应写入.
     * The default behavior of this method is to call sendError(int sc)
     * on the wrapped response object.
     */


    public void sendError(int sc) throws IOException {
	this._getHttpServletResponse().sendError(sc);
    }

    /**
     * 使用指定的重定向位置URL向客户端发送临时重定向响应.
     * 此方法可以接受相对URL，Servlet容器必须在向客户机发送响应之前将相对URL转换为绝对URL.
     * 如果位置是相对的而没有前导"/"，容器会将其解释为相对于当前请求URI.
     * 如果位置与前导"/"相关，则容器会将其解释为相对于servlet容器根.
     * 如果响应已经提交，此方法将抛出一个IllegalStateException，使用此方法后，应将响应视为已提交，不应写入.
     *
     * The default behavior of this method is to return sendRedirect(String location)
     * on the wrapped response object.
     */
    public void sendRedirect(String location) throws IOException {
	this._getHttpServletResponse().sendRedirect(location);
    }
    
    /**
     * 设置Date类型头信息.若已经存在指定的头，则会覆盖.
     * The default behavior of this method is to call setDateHeader(String name, long date)
     * on the wrapped response object.
     */
    public void setDateHeader(String name, long date) {
	this._getHttpServletResponse().setDateHeader(name, date);
    }
    
    /**
     * 新增Date类型头信息.不管是否存在，都会追加，可允许存在多个同名的头.
     * The default behavior of this method is to call addDateHeader(String name, long date)
     * on the wrapped response object.
     */
   public void addDateHeader(String name, long date) {
	this._getHttpServletResponse().addDateHeader(name, date);
    }
    
    /**
     * 设置头信息.若已经存在指定的头，则会覆盖.
     * The default behavior of this method is to return setHeader(String name, String value)
     * on the wrapped response object.
     */
    public void setHeader(String name, String value) {
	this._getHttpServletResponse().setHeader(name, value);
    }
    
    /**
     * 新增头信息.不管是否存在，都会追加，可允许存在多个同名的头.
     * The default behavior of this method is to return addHeader(String name, String value)
     * on the wrapped response object.
     */
     public void addHeader(String name, String value) {
	this._getHttpServletResponse().addHeader(name, value);
    }
    
    /**
     * 设置int类型头信息.若已经存在指定的头，则会覆盖.
     * The default behavior of this method is to call setIntHeader(String name, int value)
     * on the wrapped response object.
     */
    public void setIntHeader(String name, int value) {
	this._getHttpServletResponse().setIntHeader(name, value);
    }
    
    /**
     * 新增int类型头信息.不管是否存在，都会追加，可允许存在多个同名的头.
     * The default behavior of this method is to call addIntHeader(String name, int value)
     * on the wrapped response object.
     */
    public void addIntHeader(String name, int value) {
	this._getHttpServletResponse().addIntHeader(name, value);
    }

    /**
     * 设置response的状态码.
     * 此方法被用来设置成功状态码，出现错误设置状态码使用sendError方法.
     * 例如：SC_OK、SC_MOVED_TEMPORARILY.
     * The default behavior of this method is to call setStatus(int sc)
     * on the wrapped response object.
     */


    public void setStatus(int sc) {
	this._getHttpServletResponse().setStatus(sc);
    }
    
    /**
     * 设置response的状态码.
     * 此方法被用来设置成功状态码，出现错误设置状态码使用sendError方法.
     * 例如：SC_OK、SC_MOVED_TEMPORARILY.
     * The default behavior of this method is to call setStatus(int sc, String sm)
     * on the wrapped response object.
     */
     public void setStatus(int sc, String sm) {
	this._getHttpServletResponse().setStatus(sc, sm);
    }

   
}
